<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>手写promiseAll</title>
  <style>
    *,
    *::after,
    *::before {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    :root {
      min-height: 100vh;
    }

    :root:focus-within {
      scroll-behavior: smooth;
    }

    body {
      min-height: inherit;
    }
  </style>
</head>

<body>
  <div></div>
</body>
<script>
  "use strict"; {
    let t1 = (flag = true) => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (flag) {
            resolve("我是t1")
          } else {
            reject("出错了吧")
          }
        }, 3 * 1000)
      })
    }

    let t2 = () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("t2了吧")
        }, 1 * 1000)
      })
    }

    // 手动实现promise.all的方法
    Promise.all([t1(false), t2()])
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      })
      .finally(() => {
        console.log("结束了")
      })

    // 手动实现promise.all的方法
    class myPromiseAll {
      constructor() { }
      static all(arr) {
        if (!Array.isArray(arr)) return console.error("请传入一个数组")
        // 判断是否为 promise 对象
        let isPromise = obj => (!!obj &&
          (typeof obj === "object" || typeof obj === "function") &&
          typeof obj.then === "function");

        return new Promise((resolve, reject) => {
          let len = arr.length
          let res = new Array(len)
          let index = 0

          // 添加数据的方法
          let addData = (k, v) => {
            res[k] = v
            index++
            // 当index等于数组长度，既已经处理完毕了
            if (index === arr.length) resolve(res)
          }

          for (let i = 0; i < len; i++) {
            // 不是 Promise 对象时就跳过，直接将结果放入 res 中
            if (!isPromise(arr[i])) {
              addData(i, arr[i])
              // continue 后面的内容不再处理了
              continue
            }

            // 处理 promise 的方法了
            arr[i]
              .then(data => {
                // 把得到的结果放入到 res 中
                addData(i, data)
              })
              .catch(err => {
                reject(err)
              })
          }
        })
      }
    }

    // 手动实现promise的方法
    new myPromiseAll().all(["好的", t2(), t1(false)])
      .then(res => {
        console.log("res", res)
      }).catch(err => {
        console.error(err)
      })

    myPromiseAll.all(["好的", t1(), t2()])
      .then(res => {
        console.log("res", res)
      }).catch(err => {
        console.error(err)
      })
  };
</script>

</html>